package tools.chapter15;

import com.sun.deploy.nativesandbox.comm.Response;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Kevin
 * @date 2020/2/24 15:29
 * Dubbo中DefaultFuture.get异步转同步，简单实现
 */
public class DefaultFuture {
    private final Lock lock = new ReentrantLock();
    private final Condition done = lock.newCondition();
    String response ="xxx";

    //调用方法等待结果
    Object get(long timeout) throws TimeoutException {
        long start = System.nanoTime();
        lock.lock();
        try {
            while (!isDone()) {
                done.await(timeout,TimeUnit.SECONDS);
                long cur = System.nanoTime();
                if (isDone() || cur - start > timeout) break;;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        if (!isDone()) {
            throw new TimeoutException();
        }
        return returnFromResponse();
    }
    // RPC结果是否已经返回
    boolean isDone() {
        return response != null;
    }
    //RPC结果返回时调用该方法
    private void doReceived(Response res) {
        lock.lock();
        try {
            response = res.toString();
            if (done != null) {
                done.signal();
            }
        } finally {
            lock.unlock();
        }
    }

    //这个是自己构的，只是为了程序不报错
    private Object returnFromResponse() {
        return (Object)response;
    }

}
